﻿// 2013.10.28. Külön függvény a betöltési módoknak, értékellenőrzés, nem menedzselt objektumok kezelése.

using JellystonePark.Model;
using System;
using System.Collections.Generic;
using System.Media;
using System.IO;

namespace JellystonePark.Desktop.Data
{
    /// <summary>
    /// Jellystone játéktábla fájlkezelő típusa.
    /// </summary>
    public static class JellystoneFileManager
    {

        /// <summary>
        /// Játéktáblák betöltése erőforrásként tárolt szöveges állományból.
        /// </summary>
        /// <param name="levels"></param>
        /// <returns>A beolvasott játéktáblák listája.</returns>
        public static List<JellystoneTable> LoadResource(String levels)
        {
            MemoryStream stream = new MemoryStream();
            StreamWriter writer = new StreamWriter(stream);
            StreamReader reader = new StreamReader(stream);
            try
            {
                    writer.Write(levels);
                    writer.Flush();
                    stream.Position = 0;
                    return LoadToTable(reader);
            }
            catch (Exception e)
            {
                throw new JellystoneLevelException("Pályacsomag betöltése sikertelen:" + Environment.NewLine + e.Message);
            }
            finally
            {
                if (null != writer)
                    writer.Close();
                if (null != stream)
                    stream.Close();
                if (null != reader)
                    reader.Close();
            }
        }

        /// <summary>
        /// Játéktáblák betöltése külső szöveges állományból.
        /// </summary>
        /// <param name="levels"></param>
        /// <returns>A beolvasott játéktáblák listája.</returns>
        /// <exception cref="JellystoneLevelException">Ha nem sikerül betölteni a pályacsomagot.</exception>
        public static List<JellystoneTable> LoadFile(String levels)
        {
            StreamReader reader = new StreamReader(levels);
            try
            {
                return LoadToTable(reader);
            }
            catch (Exception e)
            {
                throw new JellystoneLevelException("Pályacsomag betöltése sikertelen:" + Environment.NewLine + e.Message);
            }
            finally
            {
                reader.Close();
            }
        }

        /// <summary>
        /// Beolvassa a játéktáblákat és ellenőrzni az értékek helyességét.
        /// </summary>
        /// <param name="reader">A "reader" paraméter karbantartása a külső folyamat felelőssége.</param>
        /// <returns>A beolvasott játéktábla.</returns>
        /// <exception cref="ArgumentException">Ha helytelen adatot tartalmaz a betöltendő állomány.</exception>
        private static List<JellystoneTable> LoadToTable(StreamReader reader)
        {
            List<JellystoneTable> tables = new List<JellystoneTable>();

            while (!reader.EndOfStream)
            {
                String[] numbers = reader.ReadLine().Split(' ');
                if ("1" != numbers[0])
                    throw new ArgumentException("Maci Laci a bal felső sarokból kell hogy induljon!");
                
                JellystoneTable table = new JellystoneTable(numbers.GetLength(0));

                for (int i = 0; i < table.SideLength; ++i)
                {
                    if (0 != i)
                        numbers = reader.ReadLine().Split(' ');
                    for (int j = 0; j < table.SideLength; ++j)
                    {
                        table.SetValue(j, i, (JellystoneTable.JellystoneField)int.Parse(numbers[j]));
                        if ((0 != j || 0 != i) && JellystoneTable.JellystoneField.Yogi == table[j, i])
                            throw new ArgumentException("Csak egy Maci Laci lehet a pályán!");
                    }
                }

                tables.Add(table);
            }

            return tables;
        }

        /// <summary>
        /// Hang lejátszása.
        /// </summary>
        /// <param name="s">Erőforrás állományban eltárolt .wav fájl.</param>
        public static void PlaySound(UnmanagedMemoryStream s)
        {
            using (SoundPlayer player = new SoundPlayer(s))
            {
                player.Play();
            }
        }
    }

    
}
